package com.tpshion.cloud.auth.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageInfo;
import com.tpshion.cloud.auth.domain.dto.*;
import com.tpshion.cloud.auth.domain.entity.Role;
import com.tpshion.cloud.auth.domain.entity.RoleUser;
import com.tpshion.cloud.auth.domain.entity.User;
import com.tpshion.cloud.auth.domain.vo.UserDetailVo;
import com.tpshion.cloud.auth.domain.vo.UserInfoVo;
import com.tpshion.cloud.auth.mapper.RoleMapper;
import com.tpshion.cloud.auth.mapper.RoleUserMapper;
import com.tpshion.cloud.auth.mapper.UserMapper;
import com.tpshion.cloud.auth.service.UserService;
import com.tpshion.cloud.common.support.Assert;
import com.tpshion.cloud.common.support.CoreException;
import com.tpshion.cloud.common.support.ErrorCode;
import com.tpshion.cloud.common.support.Result;
import com.tpshion.cloud.core.annotation.Permission;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;

@RestController
public class UserController {

    private static final Logger log = LoggerFactory.getLogger(UserController.class);

    @Autowired
    private UserService userService;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleUserMapper roleUserMapper;

    @GetMapping("/user/userInfos")
    @Permission("userInfo")
    public Result<?> userInfos(){
        List<User> users = userMapper.selectList(null);
        return Result.ok(users);
    }

    /**
     * 获取用户信息
     * @param userId
     * @return
     */
    @GetMapping("/user/info/{userId}")
    public Result<?> getUserInfo(@PathVariable("userId") String userId){
        log.info("*** getUserInfo userId:{}",userId);
        User user = userService.getUserInfo(userId);
        UserInfoVo userInfoVo = new UserInfoVo();
        BeanUtils.copyProperties(user, userInfoVo);
        log.info("*** userInfoVo:{}",userInfoVo);
        return Result.ok(userInfoVo);
    }

    /**
     * 分页获取用户数据
     */
    @PostMapping("/user/list")
    public Result<PageInfo> getUserList(@RequestBody @Validated QueryUserDto queryUserDto){
        queryUserDto.init();
        log.info("查询用户列表：queryUserDto:{}",queryUserDto);
        PageInfo pageInfo = userService.getUserList(queryUserDto);
        log.info("返回用户列表：pageInfo:{}",pageInfo);
        return Result.ok(pageInfo);
    }

    /**
     * 新增用户
     * @return
     */
    @PostMapping(value = "/user",params = {"action=add"})
    @Permission("user:add")
    public Result<?> addUser(@RequestBody @Validated AddUserDto addUserDto){
        log.info("*** addUser addUserDto:{}",addUserDto);
        UserDetailVo userDetailVo = userService.addUser(addUserDto);
        log.info("*** userDetailVo:{}",userDetailVo);
        return Result.ok(userDetailVo);
    }

    /**
     * 修改用户信息
     */
    @PostMapping(value = "/user",params = {"action=upd"})
    @Permission("user:update")
    public Result<?> editUser(@RequestBody @Validated EditUserDto editUserDto){
        log.info("*** editUser editUserDto:{}",editUserDto);
        UserDetailVo userDetailVo = userService.editUser(editUserDto);
        log.info("*** userDetailVo:{}",userDetailVo);
        return Result.ok(userDetailVo);
    }

    /**
     * 检查账号是否存在
     * @param account
     * @return
     */
    @GetMapping("/checkAccount/{account}")
    public Result<?> checkAccount(@PathVariable("account") String account){
        User user = userMapper.findByAccount(account);
        if(null != user){
            throw new CoreException(ErrorCode.USER_ACCOUNT_IS_EXIST);
        }
        return Result.ok();
    }

    /**
     * 检查手机号是否已被使用
     */
    @PostMapping("/checkPhone")
    public Result<?> checkPhone(@RequestBody @Validated CheckPhoneDto checkPhoneDto){
        checkPhoneDto.init();
        log.info("*** checkPhone checkPhoneDto:{}",checkPhoneDto);
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", checkPhoneDto.getPhone());
        if(!StringUtils.isEmpty(checkPhoneDto.getUserId())){
            queryWrapper.ne("id", checkPhoneDto.getUserId());
        }
        Integer count = userMapper.selectCount(queryWrapper);
        Assert.isTrue(count <= 0, ErrorCode.USER_PHONE_IS_EXIST);
        return Result.ok();
    }

    /**
     * 检查邮箱是否已被使用
     */
    @PostMapping("/checkEmail")
    public Result<?> checkEmail(@RequestBody @Validated CheckEmailDto checkEmailDto){
        checkEmailDto.init();
        log.info("*** checkEmail checkEmailDto:{}",checkEmailDto);
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("email", checkEmailDto.getEmail());
        if(!StringUtils.isEmpty(checkEmailDto.getUserId())){
            queryWrapper.ne("id", checkEmailDto.getUserId());
        }
        Integer count = userMapper.selectCount(queryWrapper);
        Assert.isTrue(count <= 0, ErrorCode.USER_EMAIL_IS_EXIST);
        return Result.ok();
    }

    @GetMapping("/role/{userId}")
    public Result<?> getRole(@PathVariable("userId") String userId){
        Role role = roleMapper.getByUserId(userId);
        return Result.ok(role);
    }

    @GetMapping("/roles")
    public Result<?> getAllRoles(){
        List<Role> roles = roleMapper.selectList(null);
        return Result.ok(roles);
    }

    /**
     * 删除用户
     */
    @PostMapping(value = "/user",params = {"action=del"})
    @Permission("user:delete")
    public Result<?> deleteUser(@RequestParam("userId") String userId){
        log.info("*** deleteUser userId:{}",userId);
        //查询用户是否存在
        Assert.notNull(userMapper.selectById(userId), ErrorCode.USER_NOT_EXIST);
        int i = userMapper.deleteById(userId);
        Assert.isTrue(i > 0, ErrorCode.USER_DETELE_ERROR);
        QueryWrapper<RoleUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        roleUserMapper.delete(queryWrapper);
        return Result.ok();
    }

}
